import 'dart:io';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';

/// RectImage控件 - 显示图片指定矩形区域的自定义控件
/// 使用Canvas绘制实现高性能的图片裁剪显示
class RectImage extends StatefulWidget {
  final ui.Image? image;
  final String? imagePath;
  
  /// 源图片中的矩形区域
  final double sourceX;
  final double sourceY;
  final double sourceWidth;
  final double sourceHeight;
  
  /// 控件尺寸
  final double? width;
  final double? height;
  
  /// 适配方式
  final BoxFit fit;
  
  /// 错误时显示的控件
  final Widget? errorWidget;
  
  /// 占位符控件
  final Widget? placeholder;
  
  const RectImage({
    super.key,
    required this.image,
    this.imagePath,
    required this.sourceX,
    required this.sourceY,
    required this.sourceWidth,
    required this.sourceHeight,
    this.width,
    this.height,
    this.fit = BoxFit.cover,
    this.errorWidget,
    this.placeholder,
  });
  
  /// 工厂方法：从图片路径创建RectImage
  factory RectImage.fromImage({
    required String imagePath,
    required double sourceX,
    required double sourceY,
    required double sourceWidth,
    required double sourceHeight,
    double? width,
    double? height,
    BoxFit fit = BoxFit.cover,
    Widget? errorWidget,
    Widget? placeholder,
  }) {
    return RectImage(
      image: null,
      imagePath: imagePath,
      sourceX: sourceX,
      sourceY: sourceY,
      sourceWidth: sourceWidth,
      sourceHeight: sourceHeight,
      width: width,
      height: height,
      fit: fit,
      errorWidget: errorWidget,
      placeholder: placeholder,
    );
  }

  @override
  State<RectImage> createState() => _RectImageState();
}

class _RectImageState extends State<RectImage> {
  ui.Image? _image;
  bool _isLoading = true;
  bool _hasError = false;
  String? _errorMessage;

  @override
  void initState() {
    super.initState();
    _loadImage();
  }

  @override
  void didUpdateWidget(RectImage oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.image != widget.image || oldWidget.imagePath != widget.imagePath) {
      _loadImage();
    }
  }

  @override
  void dispose() {
    _image?.dispose();
    super.dispose();
  }

  /// 异步加载图片
  Future<void> _loadImage() async {
    setState(() {
      _isLoading = true;
      _hasError = false;
      _errorMessage = null;
    });

    try {
      if (widget.image != null) {
        // 如果已经提供了ui.Image对象，直接使用
        setState(() {
          _image?.dispose();
          _image = widget.image;
          _isLoading = false;
        });
      } else if (widget.imagePath != null) {
        // 从文件路径加载图片
        final file = File(widget.imagePath!);
        if (!await file.exists()) {
          throw Exception('图片文件不存在: ${widget.imagePath}');
        }

        final bytes = await file.readAsBytes();
        final codec = await ui.instantiateImageCodec(bytes);
        final frame = await codec.getNextFrame();
        
        if (mounted) {
          setState(() {
            _image?.dispose();
            _image = frame.image;
            _isLoading = false;
          });
        }
      } else {
        throw Exception('没有提供图片或图片路径');
      }
    } catch (e) {
      if (mounted) {
        setState(() {
          _isLoading = false;
          _hasError = true;
          _errorMessage = e.toString();
        });
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    Widget child;
    
    if (_isLoading) {
      child = widget.placeholder ?? 
          Container(
            color: Colors.grey[200],
            child: const Center(
              child: SizedBox(
                width: 16,
                height: 16,
                child: CircularProgressIndicator(strokeWidth: 2),
              ),
            ),
          );
    } else if (_hasError) {
      child = widget.errorWidget ??
          Container(
            color: Colors.grey[200],
            child: Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  const Icon(
                    Icons.error_outline,
                    color: Colors.red,
                    size: 16,
                  ),
                  const SizedBox(height: 2),
                  Text(
                    '加载失败',
                    style: TextStyle(
                      fontSize: 8,
                      color: Colors.red[700],
                    ),
                  ),
                ],
              ),
            ),
          );
    } else if (_image != null) {
      child = CustomPaint(
        painter: _RectImagePainter(
          image: _image!,
          sourceRect: Rect.fromLTWH(
            widget.sourceX,
            widget.sourceY,
            widget.sourceWidth,
            widget.sourceHeight,
          ),
          fit: widget.fit,
        ),
      );
    } else {
      // 没有图片时显示错误
      child = widget.errorWidget ??
          Container(
            color: Colors.grey[200],
            child: const Center(
              child: Icon(
                Icons.image_not_supported,
                color: Colors.grey,
                size: 16,
              ),
            ),
          );
    }

    return SizedBox(
      width: widget.width,
      height: widget.height,
      child: child,
    );
  }
}

/// 自定义画笔，用于绘制图片的指定矩形区域
class _RectImagePainter extends CustomPainter {
  final ui.Image image;
  final Rect sourceRect;
  final BoxFit fit;

  _RectImagePainter({
    required this.image,
    required this.sourceRect,
    required this.fit,
  });

  @override
  void paint(Canvas canvas, Size size) {
    if (size.isEmpty) return;

    // 计算目标矩形
    final destRect = Offset.zero & size;
    
    // 验证源矩形是否在图片范围内
    final imageRect = Offset.zero & Size(image.width.toDouble(), image.height.toDouble());
    final clippedSourceRect = sourceRect.intersect(imageRect);
    
    if (clippedSourceRect.isEmpty) return;

    // 根据fit参数计算最终的绘制区域
    Rect finalDestRect;
    Rect finalSourceRect = clippedSourceRect;

    switch (fit) {
      case BoxFit.fill:
        finalDestRect = destRect;
        break;
      case BoxFit.contain:
        finalDestRect = _getContainRect(clippedSourceRect, destRect);
        break;
      case BoxFit.cover:
        final scale = _getCoverScale(clippedSourceRect, destRect);
        final scaledSourceSize = clippedSourceRect.size * scale;
        final offset = Offset(
          (scaledSourceSize.width - destRect.width) / 2,
          (scaledSourceSize.height - destRect.height) / 2,
        );
        finalDestRect = destRect;
        finalSourceRect = Rect.fromLTWH(
          clippedSourceRect.left + offset.dx / scale,
          clippedSourceRect.top + offset.dy / scale,
          destRect.width / scale,
          destRect.height / scale,
        ).intersect(imageRect);
        break;
      case BoxFit.fitWidth:
        final scale = destRect.width / clippedSourceRect.width;
        final scaledHeight = clippedSourceRect.height * scale;
        finalDestRect = Rect.fromLTWH(
          destRect.left,
          destRect.top + (destRect.height - scaledHeight) / 2,
          destRect.width,
          scaledHeight,
        );
        break;
      case BoxFit.fitHeight:
        final scale = destRect.height / clippedSourceRect.height;
        final scaledWidth = clippedSourceRect.width * scale;
        finalDestRect = Rect.fromLTWH(
          destRect.left + (destRect.width - scaledWidth) / 2,
          destRect.top,
          scaledWidth,
          destRect.height,
        );
        break;
      case BoxFit.none:
        final centerX = destRect.center.dx;
        final centerY = destRect.center.dy;
        finalDestRect = Rect.fromLTWH(
          centerX - clippedSourceRect.width / 2,
          centerY - clippedSourceRect.height / 2,
          clippedSourceRect.width,
          clippedSourceRect.height,
        );
        break;
      case BoxFit.scaleDown:
        if (clippedSourceRect.width <= destRect.width && 
            clippedSourceRect.height <= destRect.height) {
          // 图片比容器小，使用none模式
          final centerX = destRect.center.dx;
          final centerY = destRect.center.dy;
          finalDestRect = Rect.fromLTWH(
            centerX - clippedSourceRect.width / 2,
            centerY - clippedSourceRect.height / 2,
            clippedSourceRect.width,
            clippedSourceRect.height,
          );
        } else {
          // 图片比容器大，使用contain模式
          finalDestRect = _getContainRect(clippedSourceRect, destRect);
        }
        break;
    }

    // 绘制图片
    canvas.drawImageRect(image, finalSourceRect, finalDestRect, Paint());
  }

  /// 计算contain模式下的目标矩形
  Rect _getContainRect(Rect sourceRect, Rect destRect) {
    final sourceAspectRatio = sourceRect.width / sourceRect.height;
    final destAspectRatio = destRect.width / destRect.height;

    double finalWidth, finalHeight;
    if (sourceAspectRatio > destAspectRatio) {
      finalWidth = destRect.width;
      finalHeight = finalWidth / sourceAspectRatio;
    } else {
      finalHeight = destRect.height;
      finalWidth = finalHeight * sourceAspectRatio;
    }

    final offsetX = (destRect.width - finalWidth) / 2;
    final offsetY = (destRect.height - finalHeight) / 2;

    return Rect.fromLTWH(
      destRect.left + offsetX,
      destRect.top + offsetY,
      finalWidth,
      finalHeight,
    );
  }

  /// 计算cover模式下的缩放比例
  double _getCoverScale(Rect sourceRect, Rect destRect) {
    final scaleX = destRect.width / sourceRect.width;
    final scaleY = destRect.height / sourceRect.height;
    return scaleX > scaleY ? scaleX : scaleY;
  }

  @override
  bool shouldRepaint(_RectImagePainter oldDelegate) {
    return oldDelegate.image != image ||
           oldDelegate.sourceRect != sourceRect ||
           oldDelegate.fit != fit;
  }
}